#include "tools/file_utils.h"

#include "tools/log_util.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>

char *convertLinuxPathToWindows(const char *linuxPath) {
    if (linuxPath == NULL) {
        return NULL;
    }

    size_t len = strlen(linuxPath);
    char *windowsPath = (char *)malloc(len + 1); // +1 for null terminator
    if (windowsPath == NULL) {
        return NULL; // Memory allocation failed
    }

    for (size_t i = 0; i < len; i++) {
        if (linuxPath[i] == '/') {
            windowsPath[i] = '\\'; // Replace '/' with '\'
        } else {
            windowsPath[i] = linuxPath[i];
        }
    }
    windowsPath[len] = '\0'; // Null-terminate the string

    return windowsPath;
}

// 获取文件流大小
int64_t get_stream_length(cef_stream_reader_t *stream) {
    if (!stream)
        return 0;

    // 保存当前流的读写位置
    int64_t current_pos = stream->tell(stream);

    // 将流的读写位置移动到末尾
    if (stream->seek(stream, 0, SEEK_END) != 0) {
        return 0; // 移动失败
    }

    // 获取流的长度
    int64_t length = stream->tell(stream);

    // 恢复流的读写位置
    stream->seek(stream, current_pos, SEEK_SET);

    return length;
}

// 复制 cef_string_multimap_t
void cef_string_multimap_copy(const cef_string_multimap_t src, cef_string_multimap_t dest) {
    if (!src || !dest)
        return;

    size_t size = cef_string_multimap_size(src);
    for (size_t i = 0; i < size; ++i) {
        cef_string_t key = {0};
        cef_string_t value = {0};
        cef_string_multimap_key(src, i, &key);
        cef_string_multimap_value(src, i, &value);
        cef_string_multimap_append(dest, &key, &value);
    }
}

/**
 * 将多字节字符串转为宽字符串 （支持UTF-8)
 * 返回值需要手动释放
 */
wchar_t *char_byte_to_wide(const char *char_byte, UINT code_page) {
    int wide_size = MultiByteToWideChar(code_page, 0, char_byte, -1, NULL, 0);
    if (wide_size == 0)
        return NULL;

    wchar_t *wide_buffer = (wchar_t *)malloc(wide_size * sizeof(wchar_t));
    if (!wide_buffer)
        return NULL;

    if (MultiByteToWideChar(code_page, 0, char_byte, -1, wide_buffer, wide_size) == 0) {
        free(wide_buffer);
        return NULL;
    }

    return wide_buffer;
}

/**
 * 将宽字符串转换为UTF-8编码
 * 需要手动释放
 */
char *wide_to_utf8(const wchar_t *wide_str) {
    int utf8_size = WideCharToMultiByte(CP_UTF8, 0, wide_str, -1, NULL, 0, NULL, NULL);
    if (utf8_size == 0)
        return NULL;

    char *utf8_buffer = (char *)malloc(utf8_size);
    if (!utf8_buffer)
        return NULL;

    if (WideCharToMultiByte(CP_UTF8, 0, wide_str, -1, utf8_buffer, utf8_size, NULL, NULL) == 0) {
        free(utf8_buffer);
        return NULL;
    }
    free(utf8_buffer);
    return utf8_buffer;
}

// 获取子路径相对于可执行文件的全路径
char *get_target_path(const char *win_path_mb) {
    // 将输入的多字节路径转为宽字符
    wchar_t *win_path_w = char_byte_to_wide(win_path_mb, CP_UTF8); // UTF-8
    if (win_path_w == NULL) {
        return NULL;
    }

    // 获取模块路径
    wchar_t exe_path[MAX_PATH] = {0};
    GetModuleFileNameW(NULL, exe_path, MAX_PATH);

    // 截取目录部分
    wchar_t *last_slash = wcsrchr(exe_path, L'\\');
    if (last_slash)
        *last_slash = L'\0';

    // 拼接目标路径
    wchar_t target_path[MAX_PATH * 2] = {0};
    swprintf(target_path, _countof(target_path), L"%s\\%s", exe_path, win_path_w);

    // 释放临时宽字符内存
    free(win_path_w);

    // 转换为UTF-8编码
    return wide_to_utf8(target_path);
}

// 读取png 字节数据
// 成功 1
// 失败 0
int read_png_file(const char *file_path, char **png_data, size_t *png_data_size) {
    FILE *file = fopen(file_path, "rb");
    if (!file) {
        LOG_ERROR("Failed to open PNG file: %s\n", file_path);
        return 0;
    }

    // 获取文件大小
    if (fseek(file, 0, SEEK_END) != 0) {
        LOG_ERROR("fseek failed: %s\n", file_path);
        fclose(file);
        return 0;
    }

    long file_size = ftell(file);
    if (file_size == -1L) {
        LOG_ERROR("ftell failed: %s\n", file_path);
        fclose(file);
        return 0;
    }
    rewind(file); // 回到文件开头

    // 分配内存
    *png_data = (char *)malloc(file_size);
    if (!*png_data) {
        LOG_ERROR("Memory allocation failed\n");
        fclose(file);
        return 0;
    }

    // 读取文件内容
    size_t read_size = fread(*png_data, 1, file_size, file);
    if (read_size != (size_t)file_size) {
        LOG_ERROR("Read incomplete: %s (expected %ld, got %zu)\n", file_path,
                  file_size, read_size);
        free(*png_data);
        *png_data = NULL;
        fclose(file);
        return 0;
    }

    fclose(file);
    *png_data_size = (size_t)file_size;
    return 1;
}